package cache

import (
	"log/slog"
	"sync"
	"sync/atomic"

	"gitee.com/gousing/cache/driver"
	"gitee.com/gousing/cache/internal"
	"gitee.com/gousing/cache/storage"
)

var (
	globalStorage atomic.Pointer[globalStore]
	globalOnce    sync.Once
)

// storage 全局默认缓存仓库
type globalStore struct {
	storage storage.Storager
}

// GetDefault 获取全局默认缓存实例
//   - 用户可通过 `SetDefault` 设置自定义默认缓存实例
//   - 如果默认实例未配置(未初始化)，将自动尝试使用默认参数进行初始化( MemoryCache )
//   - 注意： 此函数禁止内联优化，内联后会导致全局缓存 RedisCache 实例 Stop/Restart 连接异常
//
//go:noinline
func GetDefault() storage.Storager {
	if v := globalStorage.Load(); v != nil && v.storage != nil {
		return v.storage
	}
	globalOnce.Do(func() {
		memoryCache, err := driver.NewMemoryDefault()
		if err == nil {
			memoryCache.SetGlobal()
			globalStorage.Store(&globalStore{memoryCache})
		} else {
			internal.GetLogger().Error("cache: globalStore.GetDefault, memoryCache automatic failed", slog.String("error", err.Error()))
			panic("cache: globalStore.GetDefault, memoryCache automatic failed, error: " + err.Error())
		}
	})
	if v := globalStorage.Load(); v != nil && v.storage != nil {
		return v.storage
	}
	panic("cache: globalStore.GetDefault, failed to initialize default cache")
}

// SetDefault 设置全局默认缓存实例
//   - 注意： 此函数禁止内联优化，内联后会导致全局缓存 RedisCache 实例 Stop/Restart 连接异常
//
//go:noinline
func SetDefault(driver storage.Storager) {
	if driver == nil {
		internal.GetLogger().Error("cache: globalStore.SetDefault, driver is nil")
		return
	}
	driver.SetGlobal()
	globalStorage.Store(&globalStore{driver})
}
